package com.hd.batch.quartz.batch.job.reader;

import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DefaultFieldSetFactory;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * <h3>partitionjob</h3>
 * <p>ClassPathFileReader</p>
 *
 * @author : hduong
 * @version : 1.0
 * @date : 2020-09-10 17:30
 **/
@Slf4j
public class ClassPathFileReader<T> extends FlatFileItemReader<T> {

    private ClassPathResource classPathResource;

    private static final String DEFAULT_ENCODE = "UTF-8";

    public ClassPathFileReader(String fileName, Class clazz, String delimiter, String encoding) {
        setEncoding(encoding == null || "".equals(encoding) ? DEFAULT_ENCODE : encoding);
        classPathResource = new ClassPathResource(fileName);
        setResource(classPathResource);
        DefaultLineMapper mapper = new DefaultLineMapper();
        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setFieldSetFactory(new DefaultFieldSetFactory());
        Field[] fields = clazz.getDeclaredFields();
        List<String> list = new ArrayList<>();
        for (Field field : fields) {
            if(!Modifier.isStatic(field.getModifiers())) {
                list.add(field.getName());
            }
        }
        String[] names = new String[list.size()];
        lineTokenizer.setNames(list.toArray(names));
        lineTokenizer.setDelimiter(delimiter == null || "".equals(delimiter) ? DelimitedLineTokenizer.DELIMITER_COMMA : delimiter);
        mapper.setLineTokenizer(lineTokenizer);

        BeanWrapperFieldSetMapper wrapperFieldSetMapper = new BeanWrapperFieldSetMapper();
        wrapperFieldSetMapper.setTargetType(clazz);
        mapper.setFieldSetMapper(wrapperFieldSetMapper);

        setLineMapper(mapper);

        setStrict(true);
    }

    @Override
    public T read() throws Exception, UnexpectedInputException, ParseException {
        try {
            return super.read();
        } catch (Exception e) {
            throw new Exception("文件解析不正常的数据: " + e);
        }

    }
}
